#include "city_actor.h"
#include "city_node.h"
#include "city_map.h"
#include "city_path.h"

#include "console/console.h"
#include "font/font_manager.h"
#include "dd/dd_man.h"
#include "util/timer.h"				// log
#include "util/log.h"				// log
#include "util/common_macros.h"		// macros
#include "util/mmgr.h"		    
#include "script/scripthelper.h"
#include <luabind/luabind.hpp>

using namespace city;


CityActor::CityActor(CityMap* pMap) :
	m_pMap(pMap),
	m_Type(0),
	m_pCurrent(NULL),
	m_pNext(NULL),
	m_Progress(1),
	m_pTarget(0)
{

}

CityActor::~CityActor()
{

}

void	CityActor::Create(const std::string& Sprite)
{
	m_Sprite.Create(Sprite);
}

void	CityActor::TurnEnded()
{
	if (m_pNext)
	{
		m_pCurrent = m_pNext;
		if (m_GraphPath.size() > 1)
		{
			m_pNext = m_pMap->GetNode(m_GraphPath[1]);
			m_GraphPath.erase(m_GraphPath.begin());
		}
	}
}

void	CityActor::Tick(float dt)
{
	m_Sprite.Tick(dt);
}

void	CityActor::RenderDebug()
{
	// render path
	for (int i=0; i<(int)m_GraphPath.size()-1; i++)
	{
		int	From = m_GraphPath[i];
		int	To =m_GraphPath[i+1];
		
		CityNode*	pFrom=m_pMap->GetNode(From);
		CityNode*	pTo=m_pMap->GetNode(To);

		if (pFrom && pTo)
		{
			dd::Manager::Instance().AddLine2D(
				pFrom->GetPos()-m_pMap->GetOffset(),
				pTo->GetPos()-m_pMap->GetOffset(),
				ColorRGBA(0, 255, 0, 255), false);
		}
	}
}

void	CityActor::Render()
{
	math::Vec2	P = GetPos();
	P.x -= m_Sprite.m_Size.x * 0.5f;
	P.y -= m_Sprite.m_Size.y;
	m_Sprite.Setup(P - m_pMap->GetOffset(), m_Sprite.m_Size);
	m_Sprite.Render();
	//RenderDebug();
}

math::Vec2	CityActor::GetPos()
{
	if (!m_pCurrent) return math::Vec2(0,0);

	bool	Reverse = false;
	CityPath*	pPath =m_pMap->GetConnection(m_pCurrent, m_pNext, Reverse);
	if (!m_pNext || !pPath)		// no end point, or they're not connected
	{
		return m_pCurrent->GetPos();
	}
	float Len = pPath->GetSpline().GetTrackLen();
	float Prog = m_Progress;
	if (Reverse) Prog = 1.0f - Prog;
	float Pos = Len * Prog;
	return pPath->GetSpline().GetPos(Pos);
}

void	CityActor::SetCurrent(CityNode* pNode)
{
	m_pCurrent = pNode;
	m_Progress=0;
}

void	CityActor::SetNext(CityNode* pNode)
{
	m_pNext = pNode;
	// check if it's actually connected?
}

void	CityActor::SetTarget(CityNode* pNode)
{
	m_pTarget = pNode;
	if (m_pCurrent && m_pTarget)
	{
		m_pMap->GetGraph()->FindPath(m_pCurrent->GetID(), m_pTarget->GetID(),  m_GraphPath);
		if (m_GraphPath.size() > 1)
		{
			m_pNext = m_pMap->GetNode(m_GraphPath[1]);
			m_GraphPath.erase(m_GraphPath.begin());
		}
	}

}
